package com.jfinal.ext.util;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

/**
 * @author 江理_网猿 (timor)
 * @date 2021/1/26 0026
 */
public class ArrayUtil {
    private static final Map<String, String> TYPE_MAPPING = Map.of(
        "byte", "java.lang.Byte",
        "short", "java.lang.Short",
        "char", "java.lang.Character",
        "int", "java.lang.Integer",
        "long", "java.lang.Long",
        "float", "java.lang.Float",
        "double", "java.lang.Double",
        "boolean", "java.lang.Boolean");

    private ArrayUtil(){}

    /**
     * 若为原生类型，强转会抛出异常，故封装一层, 以支持原生类型和拓展类型
     * @param obj arrayObject
     * @return objectArray
     */
    public static Object[] castToArray(@NotNull Object obj){
        if (!obj.getClass().isArray()){
            return new Object[0];
        }

        Class<?> componentType = obj.getClass().getComponentType();

        if (!TYPE_MAPPING.containsKey(componentType.getName())){
            return (Object[]) obj;
        }

        final int length = Array.getLength(obj);

        return Arrays.copyOf((Object[])obj, length, Object[].class);
    }

    public static <T> T[] castToArray(@NotNull Stream<T> stream) {
        return castToArray(stream.toList());
    }

    @SuppressWarnings("unchecked")
    public static <T> T[] castToArray(@NotNull List<T> list) {
        if (list.isEmpty()) {
            return (T[]) new Object[0];
        }


        final T[] items = (T[]) Array.newInstance(list.get(0).getClass(), list.size());

        int index = 0;

        for (T item : list) {
            items[index++] = item;
        }

        return items;
    }


    public static List<Object> castToList(@NotNull Object obj){
        return new ArrayList<>(Arrays.asList(castToArray(obj)));
    }
}
